(ns picture_gallery.routes.upload
  (:require [compojure.core :refer [defroutes GET POST]]
            [hiccup.form :refer :all]
            [hiccup.element :refer [image]]
            [hiccup.util :refer [url-encode]]
            [picture-gallery.views.layout :as layout]
            [picture_gallery.util :refer :all]
            [noir.io :refer [upload-file resource-path]]
            [noir.session :as session]
            [noir.response :as resp]
            [noir.util.route :refer [restricted]]
            [clojure.java.io :as io]
            [ring.util.response :refer [file-response]]
            [picture_gallery.models.db :as db]
            [noir.util.route :refer [restricted]]
            [noir.util.anti-forgery :refer :all]
            )
  (:import [java.io File FileInputStream FileOutputStream]
           [java.awt.image AffineTransformOp BufferedImage]
           java.awt.RenderingHints
           java.awt.geom.AffineTransform
           javax.imageio.ImageIO))

(def thumb-size 150)

(defn scale [img ratio width height]
  (let [scale (AffineTransform/getScaleInstance
                (double ratio) (double ratio))
        transform-op (AffineTransformOp. scale AffineTransformOp/TYPE_BILINEAR)]
    (.filter transform-op img (BufferedImage. width height (.getType img)))))

(defn scale-image [file]
  (let  [img (ImageIO/read file)
         img-width (.getWidth img)
         img-height (.getHeight img)
         ratio (/ thumb-size img-height)]
    (scale img ratio (int (* img-width ratio)) thumb-size)))

(defn save-thumbnail [{:keys [filename]}] ;保存
  (let [path (str (gallery-path) File/separator)]
    (ImageIO/write
      (scale-image (io/input-stream (str path filename)))
      "jpeg"
      (File. (str path thumb-prefix filename)))))

(defn upload-page [info]
  ;(println (str "upload:" (session/get :user)))
  (layout/common
    [:h2 "Upload an image"]
    [:p info]
    (form-to {:enctype "multipart/form-data"}
             [:post "/upload"]
             (anti-forgery-field)
             (file-upload :file)
             (submit-button "upload")))
  )

(defn handle-upload [{:keys [filename] :as file}]
  ;(println file)
  (upload-page
    (if (empty? filename)
    "Please select a file to upload"
      (try
        (noir.io/upload-file (gallery-path) file :create-path? true) ;上传file文件到(gallery-path)路径
        (save-thumbnail file)                               ;保存缩略图
        (db/add-image (session/get :user) filename)
        (image {:height "150px"}                            ;显示缩略图
               (thumb-uri (session/get :user) filename))
        (catch Exception ex
          (str "error uploading file" (.getMessage ex)))))))

(defn serve-file [user-id file-name]
  (file-response (str galleries File/separator user-id File/separator file-name)))

(defroutes upload-routes
           (GET "/upload" [info] (restricted (upload-page info)))
           (GET "/img/:user-id/:file-name" [user-id file-name]
             (serve-file user-id file-name))
           (POST "/upload" [file] (restricted (handle-upload file))))